#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,a,b) for(register int i = (a);i <= (b);++i)
#define per(i,a,b) for(register int i = (a);i >= (b);--i) 
#define mkp std::make_pair
typedef long long ll;
typedef unsigned long long ull;
using std::string;using std::cin;using std::cout;
inline bool cmp(int x,int y){return x < y;}

const int N = 1e6+9;
const int inf = 1e9+9;
const double eps = 1e-7;
int _,n,m,a[2*N],u,v;
char ch;

int next[2*N],ver[2*N],head[2*N],tot;
double edge[2*N],di[200][200],ans,d[200];

struct node{
    int x,y;
}e[2*N];

inline double dis(int p,int q){return sqrt((e[p].x - e[q].x)*(e[p].x - e[q].x) + (e[p].y - e[q].y)*(e[p].y - e[q].y));}
inline void link(int x,int y){ver[++tot] = y , next[tot] = head[x] , head[x] = tot , edge[tot] = dis(x,y);}


int main(){
    std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    #ifdef LOCAL //use "g++ xxx.cpp -DLOCAL"
        freopen("in.in", "r", stdin);
    #endif
    cin >> n;
    rep(i,1,n){
        cin >> u >> v;
        e[i].x = u , e[i].y = v; 
    }
    rep(i,1,n) rep(j,1,n) di[i][j] = inf;
    rep(i,1,n) rep(j,1,n){
        cin >> ch;
        u = ch-'0';
        if(u) di[i][j] = dis(i,j);
    }
    //Floyd
    rep(k,1,n) rep(i,1,n) rep(j,1,n) if(di[i][k] + di[k][j] < di[i][j]) di[i][j] = di[i][k] + di[k][j];
    rep(i,1,n) rep(j,1,n) if(di[i][j] != inf && i != j) ans = std::max(ans,di[i][j]) , d[i] = std::max(d[i],di[i][j]) ;    
    double anss = inf;
    rep(i,1,n) rep(j,1,n) if(di[i][j] == inf){
        if(i == j) continue;
        anss = std::min(anss,d[i] + d[j] + dis(i,j));
        // cout << anss << " " << d[i] << " " << d[j] << " " << dis(i,j) << " " << i << " " << j << "\n";
    }
    printf("%.6lf\n",std::max(ans,anss));

    return 0;
}